﻿
#region Using Directives.

using System;
using System.Globalization;
using System.IO;
using System.Drawing;
using TagLib;
using TagLib.Ogg;
using File = TagLib.File;

#endregion

namespace GDFlacTool.Common
{
    [Serializable]
    public class TrackFlac : Track
    {
        #region Fields.

        private File _taglibfile;
        private XiphComment _xiphComment;
        private readonly bool _isEmpty;
        private readonly string _trackFormat = string.Empty;
        private readonly bool _isSupportedFormat;

        #endregion

        #region Constructors.

        public TrackFlac() { }

        public TrackFlac(string path)
        {
            FullPath = path;

            _trackFormat = "flac";

            _isSupportedFormat = true;

            if (CreateTagLibFile(FullPath))
            {
                ReadFileInfo();

                ReadTags();

                _isEmpty = false;
            }
            else
            {
                FullPath = string.Empty;

                _isEmpty = true;
            }
        }

        #endregion

        #region Public Methods.

        public void RemoveTag(string tag)
        {
            _xiphComment.RemoveField(tag);
        }

        public void ClearTrack()
        {
            _xiphComment.Clear();

            ReadTags();
        }

        #endregion

        #region Override Methods.

        public override bool IsEmpty
        {
            get { return _isEmpty; }
        }

        public override string TrackFormat
        {
            get { return _trackFormat; }
        }

        public override bool IsSupportedTag
        {
            get { return _isSupportedFormat; }
        }

        public override void SetTag(string tagtype)
        {
            switch (tagtype)
            {
                case "TRACKNUMBER":
                    _xiphComment.SetField(TagType.Tracknumber, new[] { TrackNumber });
                    _taglibfile.Save();
                    break;
                case "DISCNUMBER":
                    _xiphComment.SetField(TagType.Discnumber, new[] { DiscNumber });
                    _taglibfile.Save();
                    break;
                case "TITLE":
                    _xiphComment.SetField(TagType.Title, new[] { Title });
                    _taglibfile.Save();
                    break;
            }
        }

        public override void SetTag(params string[] tagtype)
        {
            foreach (string s in tagtype)
            {
                SetTag(s);
            }
        }

        public override void SaveFrontCoverArt(byte[] bytes)
        {
            MemoryStream ms = null;

            try
            {
                ms = new MemoryStream(bytes);

                Picture picture = new Picture();

                picture.Type = PictureType.FrontCover;
                picture.MimeType = "image/jpeg";
                picture.Description = "Front Cover";
                picture.Data = ByteVector.FromStream(ms);

                _taglibfile.Tag.Pictures = new IPicture[] { picture };

                base.ArtSize = _taglibfile.Tag.Pictures[0].Data.Data.Length;

                _taglibfile.Save();
            }
            catch (Exception ex)
            {
                throw new SaveArtException(ex.Message, "Failed to save the cover art to the file");
            }
            finally
            {
                if (ms != null) ms.Close();
            }

            ReadFrontCoverArt();
        }

        public override void RemoveFrontCoverArt()
        {
            foreach (IPicture picture in _taglibfile.Tag.Pictures)
            {
                if (picture.Type == PictureType.FrontCover)
                {
                    picture.Type = PictureType.Other;
                    picture.Data.Clear();
                }
            }

            _taglibfile.Save();

            ArtImage = null;
            ArtByteArray = null;
            ArtSize = 0;
        }

        public override void ClearUndo()
        {
            if (IsTrackRenamed)
            {
                Trackrename = null;
            }
        }

        public override bool RenameTrack(MaskHelperCollection masks, TrackRename trackRename)
        {
            string newFileName = masks.Mask;
            int counter = 1;
            Trackrename = trackRename;

            foreach (MaskHelper mask in masks)
            {
                if (newFileName.Contains(mask.Mask))
                {
                    if (mask.IsStandardTag)
                    {
                        string replace = ReplaceStandardTags(mask.TagType);

                        if (replace != null)
                        {
                            newFileName = newFileName.Replace(mask.Mask, replace);
                        }
                    }
                    else
                    {
                        string replace = ReplaceNonStandardTags(mask.TagType, counter);

                        newFileName = newFileName.Replace(mask.Mask, replace);
                    }
                }

                counter++;
            }

            string temp = newFileName.Replace(Path.AltDirectorySeparatorChar, ' ');

            if (string.IsNullOrEmpty(newFileName))
            {
                return false;
            }

            temp = Functions.RemoveIllegalCharsFileName(temp);

            string tempPath = Path.GetDirectoryName(temp);

            string newPath = string.Empty;

            if (!string.IsNullOrEmpty(tempPath))
            {
                newPath = Path.GetDirectoryName(newFileName);

                if (!Path.IsPathRooted(newPath))
                {
                    if (newPath != null) newPath = newPath.Replace(":", "_");
                }
                else
                {
                    if (newPath != null)
                    {
                        string tmp = newPath.Substring(0, 2);
                        newPath = newPath.Remove(0, 2);
                        newPath = newPath.Replace(":", "_");

                        newPath = tmp + newPath;
                    }
                }
            }

            Trackrename.RenamedPath = newPath;

            Trackrename.RenamedFileName = newFileName;

            return true;
        }

        #endregion

        #region Rename From Mask Methods.

        public override void UpdateAfterRename()
        {
            if (_taglibfile.Name != FullPath)
            {
                CreateTagLibFile(FullPath);
            }

            ReadFileInfo();
            ReadTags();
        }

        private string ReplaceNonStandardTags(MaskType type, int fileNumber)
        {
            string result;

            switch (type)
            {
                case MaskType.ENCODER:
                    result = _xiphComment.VendorId;
                    break;
                case MaskType.BITRATE:
                    result = _taglibfile.Properties.AudioBitrate.ToString(CultureInfo.InvariantCulture);
                    break;
                case MaskType.PLAYTIME:
                    result = string.Format("({0:mm}:{1:ss})", _taglibfile.Properties.Duration, _taglibfile.Properties.Duration);
                    break;
                case MaskType.FILENUMBER:
                    result = fileNumber.ToString(CultureInfo.InvariantCulture);
                    break;
                case MaskType.FILENAME:
                    result = FileName;
                    break;
                case MaskType.BPM:
                    result = _taglibfile.Properties.AudioSampleRate.ToString(CultureInfo.InvariantCulture);
                    break;
                default:
                    result = string.Empty;
                    break;
            }

            if (result == null)
            {
                result = string.Empty;
            }

            return result;
        }

        private string ReplaceStandardTags(MaskType type)
        {
            string result;

            if (type == MaskType.DATE)
            {
                result = _xiphComment.GetFirstField(TagType.Year);

                if (result == null)
                {
                    return string.Empty;
                }

                if (result == string.Empty)
                {
                    result = _xiphComment.GetFirstField(TagType.Releaseyear);
                }

                return result;
            }

            if (type == MaskType.TRACKNUMBERZERO || type == MaskType.TRACKNUMBER)
            {
                string temp = _xiphComment.GetFirstField(TagType.Tracknumber);

                if(temp == null)
                {
                    return string.Empty;
                }

                if (temp.Contains("/"))
                {
                    result = temp.Remove(temp.IndexOf("/", StringComparison.Ordinal));
                }
                else
                {
                    result = temp;
                }

                int number;

                if (int.TryParse(result, out number))
                {
                    if (type == MaskType.TRACKNUMBER)
                    {
                        result = string.Format("{0:#}", number);
                    }
                    else
                    {
                        result = string.Format("{0:0#}", number);
                    }
                }

                return result;
            }

            if (type == MaskType.DISCNUMBER || type == MaskType.DISCNUMBERZERO)
            {
                string temp = _xiphComment.GetFirstField(TagType.Discnumber);

                if (temp == null)
                {
                    return string.Empty;
                }

                if (temp.Contains("/"))
                {
                    result = temp.Remove(temp.IndexOf("/", StringComparison.Ordinal));
                }
                else
                {
                    result = temp;
                }

                int number;

                if (int.TryParse(result, out number))
                {
                    if (type == MaskType.DISCNUMBER)
                    {
                        result = string.Format("{0:#}", number);
                    }
                    else
                    {
                        result = string.Format("{0:0#}", number);
                    }
                }

                return result;
            }

            result = _xiphComment.GetFirstField(type.ToString());

            if (result == null)
            {
                result = string.Empty;
            }

            return result;
        }

        #endregion

        #region Private Methods.

        private void ReadFrontCoverArt()
        {
            MemoryStream ms = null;

            ArtImage = null;

            ArtSize = 0;

            IPicture[] pic = _taglibfile.Tag.Pictures;

            foreach (IPicture picture in pic)
            {
                if (picture.Type == PictureType.FrontCover && picture.Data.Count > 0)
                {
                    try
                    {
                        ms = new MemoryStream(picture.Data.Data, 0, picture.Data.Data.Length);
                        ms.Seek(0, SeekOrigin.Begin);
                        ArtByteArray = picture.Data.Data;
                        ArtSize = _taglibfile.Tag.Pictures[0].Data.Data.Length;
                        ArtImage = Image.FromStream(ms, false, true);
                    }
                    catch (ArgumentException)
                    {
                        RemoveFrontCoverArt();
                    }
                }
            }

            if (ms != null)
            {
                ms.Close();
            }
        }

        public override void ClearTags()
        {
            _xiphComment.Clear();

            //Clear the artist tag
            Artist = string.Empty;

            //Clear the album artist tag
            Albumartist = string.Empty;

            //Clear the album tag
            Album = string.Empty;

            //Clear the title tag
            Title = string.Empty;

            //Clear year tag
            Year = string.Empty;

            //Clear the genre tag;
            Genre = string.Empty;

            //Clear the comment tag
            Comment = string.Empty;

            //Clear the comment tag
            Catalog = string.Empty;

            //Clear the track number tag
            TrackNumber = string.Empty;

            //Clear the disc number tag
            DiscNumber = string.Empty;

            //Clear the isrc number tag
            Isrc = string.Empty;

            //Clear the release type tag
            ReleaseType = string.Empty;

            //Clear the composer tag
            Composer = string.Empty;

            //Clear the original artist tag
            Originalartist = string.Empty;

            //Clear the copyright tag
            Copyright = string.Empty;

            //Clear the url tag
            Url = string.Empty;

            //Clear the copyright tag
            EncodedBy = string.Empty;

            //Clear the mood tag
            Mood = string.Empty;

            //Clear the rating tag
            Rating = string.Empty;

            //Clear the quality tag
            Quality = string.Empty;

            //Clear the bpm tag
            Bpm = string.Empty;

            //Clear the lyrics tag
            Lyrics = string.Empty;

            //Clear the compilation tag
            Compilation = false;

            //Clear the lyricist tag
            Lyricist = string.Empty;

            //Clear the original lyricist tag
            OriginalLyricist = string.Empty;

            //Clear the radio station name tag
            RadioStationName = string.Empty;

            //Clear the label tag
            Label = string.Empty;

            //Clear the conductor tag
            Conductor = string.Empty;

            //Clear the remixed by tag
            RemixedBy = string.Empty;

            //Clear the audio file url tag
            AudioFileUrl = string.Empty;

            //Clear the audio source url tag
            AudioSourceUrl = string.Empty;

            //Clear the author url tag
            AuthorUrl = string.Empty;

            //Clear the buy cd url tag
            BuyCdUrl = string.Empty;

            //Clear the radio station url tag
            RadioStationUrl = string.Empty;

            //Clear front cover art
            RemoveFrontCoverArt();

            _taglibfile.Save();
        }

        private bool CreateTagLibFile(string path)
        {
            try
            {
                _taglibfile = File.Create(path, ReadStyle.Average);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private void ReadFileInfo()
        {
            _xiphComment = (XiphComment)_taglibfile.GetTag(TagTypes.Xiph);

            var fileInfo = new FileInfo(FullPath);

            //Create a file path
            FilePath = string.Format("{0}{1}", Path.GetDirectoryName(FullPath), Path.DirectorySeparatorChar);

            //Read the file name
            FileName = Path.GetFileName(FullPath);

            //Read bitrate
            BitRate = _taglibfile.Properties.AudioBitrate;

            //Read duration
            if (_taglibfile.Properties.Duration.Hours > 0)
            {
                Time = string.Format("{0:0#}:{1:0#}:{2:0#}", _taglibfile.Properties.Duration.Hours, _taglibfile.Properties.Duration.Minutes, _taglibfile.Properties.Duration.Seconds);
            }
            else
            {
                Time = string.Format("{0:0#}:{1:0#}", _taglibfile.Properties.Duration.Minutes, _taglibfile.Properties.Duration.Seconds);
            }

            TimeTicks = _taglibfile.Properties.Duration.Ticks;

            //Read the file size
            Size = fileInfo.Length;

            //Read the sample rate
            SampleRate = _taglibfile.Properties.AudioSampleRate.ToString(CultureInfo.InvariantCulture);

            //Read the bps
            BitsPerSample = _taglibfile.Properties.BitsPerSample.ToString(CultureInfo.InvariantCulture);

            //Read channels
            Channels = _taglibfile.Properties.AudioChannels;

            //Read the encoder info
            Encoder = _xiphComment.VendorId;
        }

        private void ReadTags()
        {
            //Read the artist tag
            string artist = _xiphComment.GetFirstField(TagType.Artist);
            if (!string.IsNullOrEmpty(artist))
            {
                Artist = artist;
            }
            else
            {
                Artist = string.Empty;
            }

            //Read the album artist tag
            string albumartist = _xiphComment.GetFirstField(TagType.Albumartist);
            string albumArtist = _xiphComment.GetFirstField(TagType.AlbumArtist);
            string h2AlbumArtist = _xiphComment.GetFirstField(TagType.H2AlbumArtist);
            if (!string.IsNullOrEmpty(albumartist))
            {
                Albumartist = albumartist;
            }
            else if (!string.IsNullOrEmpty(albumArtist))
            {
                Albumartist = albumArtist;
            }
            else if (!string.IsNullOrEmpty(h2AlbumArtist))
            {
                Albumartist = h2AlbumArtist;
            }
            else
            {
                Albumartist = string.Empty;
            }

            //Read the album tag
            string album = _xiphComment.GetFirstField(TagType.Album);
            if (!string.IsNullOrEmpty(album))
            {
                Album = album;
            }
            else
            {
                Album = string.Empty;
            }

            //Read the title tag
            string title = _xiphComment.GetFirstField(TagType.Title);
            if (!string.IsNullOrEmpty(title))
            {
                Title = title;
            }
            else
            {
                Title = string.Empty;
            }

            //Read year tag
            string year = _xiphComment.GetFirstField(TagType.Year);
            string releaseYear = _xiphComment.GetFirstField(TagType.Releaseyear);
            string h2ReleaseYear = _xiphComment.GetFirstField(TagType.H2Releaseyear);
            if (!string.IsNullOrEmpty(year))
            {
                Year = year;
            }
            else if (!string.IsNullOrEmpty(releaseYear))
            {
                Year = releaseYear;
            }
            else if (!string.IsNullOrEmpty(h2ReleaseYear))
            {
                Year = h2ReleaseYear;
            }
            else
            {
                Year = string.Empty;
            }

            //Read the genre tag;
            string genre = _xiphComment.GetFirstField(TagType.Genre);
            if (!string.IsNullOrEmpty(genre))
            {
                Genre = genre;
            }
            else
            {
                Genre = string.Empty;
            }

            //Read the comment tag
            string comment = _xiphComment.GetFirstField(TagType.Comment);
            if (!string.IsNullOrEmpty(comment))
            {
                Comment = comment;
            }
            else
            {
                Comment = string.Empty;
            }

            //Read the catalog tag
            string labelNo = _xiphComment.GetFirstField(TagType.LabelNo);
            string catalogNumber = _xiphComment.GetFirstField(TagType.CatalogNumber);
            if (!string.IsNullOrEmpty(labelNo))
            {
                Catalog = labelNo;
            }
            else if (!string.IsNullOrEmpty(catalogNumber))
            {
                Catalog = catalogNumber;
            }
            else
            {
                Catalog = string.Empty;
            }

            //Read the track number tag
            string tracknumber = _xiphComment.GetFirstField(TagType.Tracknumber);
            if (!string.IsNullOrEmpty(tracknumber))
            {
                TrackNumber = tracknumber;
            }
            else
            {
                TrackNumber = string.Empty;
            }

            //Read the disc number tag
            string discnumber = _xiphComment.GetFirstField(TagType.Discnumber);
            if (!string.IsNullOrEmpty(discnumber))
            {
                DiscNumber = discnumber;
            }
            else
            {
                DiscNumber = string.Empty;
            }

            //Read the isrc number tag
            string isrc = _xiphComment.GetFirstField(TagType.Isrc);
            if (!string.IsNullOrEmpty(isrc))
            {
                Isrc = isrc;
            }
            else
            {
                Isrc = string.Empty;
            }

            //Read the release type tag
            string releasetype = _xiphComment.GetFirstField(TagType.ReleaseType);
            if (!string.IsNullOrEmpty(releasetype))
            {
                ReleaseType = releasetype;
            }
            else
            {
                ReleaseType = string.Empty;
            }

            //Read the composer tag
            string composer = _xiphComment.GetFirstField(TagType.Composer);
            if (!string.IsNullOrEmpty(composer))
            {
                Composer = composer;
            }
            else
            {
                Composer = string.Empty;
            }

            //Read the original artist tag
            string originalartist = _xiphComment.GetFirstField(TagType.OriginalArtist);
            if (!string.IsNullOrEmpty(originalartist))
            {
                Originalartist = originalartist;
            }
            else
            {
                Originalartist = string.Empty;
            }

            //Read the copyright tag
            string copyright = _xiphComment.GetFirstField(TagType.Copyright);
            if (!string.IsNullOrEmpty(copyright))
            {
                Copyright = copyright;
            }
            else
            {
                Copyright = string.Empty;
            }

            //Read the url tag
            string url = _xiphComment.GetFirstField(TagType.Url);
            if (!string.IsNullOrEmpty(url))
            {
                Url = url;
            }
            else
            {
                Url = string.Empty;
            }

            //Read the copyright tag
            string encodedby = _xiphComment.GetFirstField(TagType.EncodedBy);
            if (!string.IsNullOrEmpty(encodedby))
            {
                EncodedBy = encodedby;
            }
            else
            {
                EncodedBy = string.Empty;
            }

            //Read the mood tag
            string mood = _xiphComment.GetFirstField(TagType.Mood);
            if (!string.IsNullOrEmpty(mood))
            {
                Mood = mood;
            }
            else
            {
                Mood = string.Empty;
            }

            //Read the rating tag
            string rating = _xiphComment.GetFirstField(TagType.Rating);
            if (!string.IsNullOrEmpty(rating))
            {
                Rating = rating;
            }
            else
            {
                Rating = string.Empty;
            }

            //Read the quality tag
            string quality = _xiphComment.GetFirstField(TagType.Quality);
            if (!string.IsNullOrEmpty(quality))
            {
                Quality = quality;
            }
            else
            {
                Quality = string.Empty;
            }

            //Read the bpm tag
            string bpm = _xiphComment.GetFirstField(TagType.Bpm);
            if (!string.IsNullOrEmpty(bpm))
            {
                Bpm = bpm;
            }
            else
            {
                Bpm = string.Empty;
            }

            //Read the bpm tag
            string lyrics = _xiphComment.GetFirstField(TagType.Lyrics);
            if (!string.IsNullOrEmpty(lyrics))
            {
                Lyrics = lyrics;
            }
            else
            {
                Lyrics = string.Empty;
            }

            //Read the compilation tag
            Compilation = _xiphComment.IsCompilation;

            //Read the lyricist tag
            string lyricist = _xiphComment.GetFirstField(TagType.Lyricist);
            if (!string.IsNullOrEmpty(lyricist))
            {
                Lyricist = lyricist;
            }
            else
            {
                Lyricist = string.Empty;
            }

            //Read the original lyricist tag
            string originallyricist = _xiphComment.GetFirstField(TagType.OriginalLyricist);
            if (!string.IsNullOrEmpty(originallyricist))
            {
                OriginalLyricist = originallyricist;
            }
            else
            {
                OriginalLyricist = string.Empty;
            }

            //Read the radio station name tag
            string radiostationname = _xiphComment.GetFirstField(TagType.RadioStationName);
            if (!string.IsNullOrEmpty(radiostationname))
            {
                RadioStationName = radiostationname;
            }
            else
            {
                RadioStationName = string.Empty;
            }

            //Read the label tag
            string label = _xiphComment.GetFirstField(TagType.Label);
            if (!string.IsNullOrEmpty(label))
            {
                Label = label;
            }
            else
            {
                Label = string.Empty;
            }

            //Read the conductor tag
            string conductor = _xiphComment.GetFirstField(TagType.Conductor);
            if (!string.IsNullOrEmpty(conductor))
            {
                Conductor = conductor;
            }
            else
            {
                Conductor = string.Empty;
            }

            //Read the remixed by tag
            string remixedby = _xiphComment.GetFirstField(TagType.RemixedBy);
            if (!string.IsNullOrEmpty(remixedby))
            {
                RemixedBy = remixedby;
            }
            else
            {
                RemixedBy = string.Empty;
            }

            //Read the audio file url tag
            string audiofileurl = _xiphComment.GetFirstField(TagType.AudioFileUrl);
            if (!string.IsNullOrEmpty(audiofileurl))
            {
                AudioFileUrl = audiofileurl;
            }
            else
            {
                AudioFileUrl = string.Empty;
            }

            //Read the audio source url tag
            string audiosourceurl = _xiphComment.GetFirstField(TagType.AudioSourceUrl);
            if (!string.IsNullOrEmpty(audiosourceurl))
            {
                AudioSourceUrl = audiosourceurl;
            }
            else
            {
                AudioSourceUrl = string.Empty;
            }

            //Read the author url tag
            string authorurl = _xiphComment.GetFirstField(TagType.AuthorUrl);
            if (!string.IsNullOrEmpty(authorurl))
            {
                AuthorUrl = authorurl;
            }
            else
            {
                AuthorUrl = string.Empty;
            }

            //Read the buy cd url tag
            string buycdurl = _xiphComment.GetFirstField(TagType.BuyCdUrl);
            if (!string.IsNullOrEmpty(buycdurl))
            {
                BuyCdUrl = buycdurl;
            }
            else
            {
                BuyCdUrl = string.Empty;
            }

            //Read the remixed by tag
            string radiostationurl = _xiphComment.GetFirstField(TagType.RadioStationUrl);
            if (!string.IsNullOrEmpty(radiostationurl))
            {
                RadioStationUrl = radiostationurl;
            }
            else
            {
                RadioStationUrl = string.Empty;
            }

            //Read fron cover art
            ReadFrontCoverArt();
        }

        public override void SetTags()
        {
            //Set the title tag
            if (IsTitleChanged)
            {
                _xiphComment.SetField(TagType.Title, new[] { Title });
                IsTitleChanged = false;
            }

            //Set the artist tag
            if (IsArtistChanged)
            {
                _xiphComment.SetField(TagType.Artist, new[] { Artist });
                IsArtistChanged = false;
            }

            //Set the album tag
            if (IsAlbumChanged)
            {
                _xiphComment.SetField(TagType.Album, new[] { Album });
                IsAlbumChanged = false;
            }

            //Set the album artist tag
            if (IsAlbumArtistChanged)
            {
                _xiphComment.SetField(TagType.Albumartist, new[] { Albumartist });
                _xiphComment.SetField(TagType.AlbumArtist, new[] { Albumartist });
                _xiphComment.SetField(TagType.H2AlbumArtist, new[] { Albumartist });
                IsAlbumChanged = false;
            }

            //Set the year tag
            if (IsYearChanged)
            {
                _xiphComment.SetField(TagType.Year, new[] { Year });
                _xiphComment.SetField(TagType.Releaseyear, new[] { Year });
                _xiphComment.SetField(TagType.H2Releaseyear, new[] { Year });
                IsYearChanged = false;
            }

            //Set the genre tag
            if (IsGenreChanged)
            {
                _xiphComment.SetField(TagType.Genre, new[] { Genre });
                IsGenreChanged = false;
            }

            //Set the comment tag
            if (IsCommentChanged)
            {
                _xiphComment.SetField(TagType.Comment, new[] { Comment });
                IsCommentChanged = false;
            }

            //Set the SHN ID tag
            if (IsCatalogChanged)
            {
                _xiphComment.SetField(TagType.LabelNo, new[] { Catalog });
                _xiphComment.SetField(TagType.CatalogNumber, new[] { Catalog });
                IsCatalogChanged = false;
            }

            //Set the track number tag
            if (IsTrackNumberChanged)
            {
                _xiphComment.SetField(TagType.Tracknumber, new[] { TrackNumber });
                IsTrackNumberChanged = false;
            }

            //Set the disc number tag
            if (IsDiscNumberChanged)
            {
                _xiphComment.SetField(TagType.Discnumber, new[] { DiscNumber });
                IsDiscNumberChanged = false;
            }

            //Set the isrc number tag
            if (IsIsrcChanged)
            {
                _xiphComment.SetField(TagType.Isrc, new[] { Isrc });
                IsIsrcChanged = false;
            }

            //Set the release type tag
            if (IsReleaseTypeChanged)
            {
                _xiphComment.SetField(TagType.ReleaseType, new[] { ReleaseType });
                IsReleaseTypeChanged = false;
            }

            //Set the composer tag
            if (IsComposerChanged)
            {
                _xiphComment.SetField(TagType.Composer, new[] { Composer });
                IsComposerChanged = false;
            }

            //Set the original artist tag
            if (IsOriginalArtistChanged)
            {
                _xiphComment.SetField(TagType.OriginalArtist, new[] { Originalartist });
                IsOriginalArtistChanged = false;
            }

            //Set the copyright tag
            if (IsCopyrightChanged)
            {
                _xiphComment.SetField(TagType.Copyright, new[] { Copyright });
                IsCopyrightChanged = false;
            }

            //Set the url tag
            if (IsUrlChanged)
            {
                _xiphComment.SetField(TagType.Url, new[] { Url });
                IsUrlChanged = false;
            }

            //Set the encoded by tag
            if (IsEncodedByChanged)
            {
                _xiphComment.SetField(TagType.EncodedBy, new[] { EncodedBy });
                IsEncodedByChanged = false;
            }

            //Set the mood by tag
            if (IsMoodChanged)
            {
                _xiphComment.SetField(TagType.Mood, new[] { Mood });
                IsMoodChanged = false;
            }

            //Set the rating by tag
            if (IsRatingChanged)
            {
                if (Rating != "0")
                {
                    _xiphComment.SetField(TagType.Rating, new[] { Rating });
                }
                else
                {
                    RemoveTag(TagType.Rating);
                }

                IsRatingChanged = false;
            }

            //Set the quality by tag
            if (IsQualityChanged)
            {
                _xiphComment.SetField(TagType.Quality, new[] { Quality });
                IsQualityChanged = false;
            }

            //Set the bpm by tag
            if (IsBpmChanged)
            {
                _xiphComment.SetField(TagType.Bpm, new[] { Bpm });
                IsBpmChanged = false;
            }

            //Set the compilation tag
            if (IsCompilationChanged)
            {
                _xiphComment.IsCompilation = Compilation;
                IsCompilationChanged = false;
            }

            //Set the lyrics tag
            if (IsLyricsChanged)
            {
                if (!string.IsNullOrEmpty(Lyrics))
                {
                    _xiphComment.SetField(TagType.Lyrics, new[] { Lyrics });
                }
                else
                {
                    RemoveTag(TagType.Lyrics);
                }

                IsLyricsChanged = false;
            }

            //Set the conductor tag
            if (IsConductorChanged)
            {
                _xiphComment.SetField(TagType.Conductor, new[] { Conductor });
                IsConductorChanged = false;
            }

            //Set the lyricist tag
            if (IsLyricistChanged)
            {
                _xiphComment.SetField(TagType.Lyricist, new[] { Lyricist });
                IsLyricistChanged = false;
            }

            //Set the original lyricist tag
            if (IsOriginalLyricistChanged)
            {
                _xiphComment.SetField(TagType.OriginalLyricist, new[] { OriginalLyricist });
                IsOriginalLyricistChanged = false;
            }

            //Set the label tag
            if (IsLabelChanged)
            {
                _xiphComment.SetField(TagType.Label, new[] { Label });
                IsLabelChanged = false;
            }

            //Set the remixed by tag
            if (IsRemixedByChanged)
            {
                _xiphComment.SetField(TagType.RemixedBy, new[] { RemixedBy });
                IsRemixedByChanged = false;
            }

            //Set the radio station name tag
            if (IsRadioStationNameChanged)
            {
                _xiphComment.SetField(TagType.RadioStationName, new[] { RadioStationName });
                IsRadioStationNameChanged = false;
            }

            //Set the audio file url tag
            if (IsAudioFileUrlChanged)
            {
                _xiphComment.SetField(TagType.AudioFileUrl, new[] { AudioFileUrl });
                IsAudioFileUrlChanged = false;
            }

            //Set the author url tag
            if (IsAuthorUrlChanged)
            {
                _xiphComment.SetField(TagType.AuthorUrl, new[] { AuthorUrl });
                IsAuthorUrlChanged = false;
            }

            //Set the audio source url tag
            if (IsAudioSourceUrlChanged)
            {
                _xiphComment.SetField(TagType.AudioSourceUrl, new[] { AudioSourceUrl });
                IsAudioSourceUrlChanged = false;
            }

            //Set the radio station url tag
            if (IsRadioStationUrlChanged)
            {
                _xiphComment.SetField(TagType.RadioStationUrl, new[] { RadioStationUrl });
                IsRadioStationUrlChanged = false;
            }

            //Set the buy cd url tag
            if (IsBuyCdUrlChanged)
            {
                _xiphComment.SetField(TagType.BuyCdUrl, new[] { BuyCdUrl });
                IsBuyCdUrlChanged = false;
            }

            _taglibfile.Save();
        }

        #endregion

        #region Old Code.

        //public Image GetFrontCoverArt(File file, out long frontCoverArtFileSize)
        //{
        //    MemoryStream ms = null;

        //    Image image = null;

        //    frontCoverArtFileSize = 0;

        //    IPicture[] pic = file.Tag.Pictures;

        //    foreach (IPicture picture in pic)
        //    {
        //        if(picture.Type == PictureType.FrontCover && picture.Data.Count > 0)
        //        {
        //            ms = new MemoryStream(picture.Data.Data);
        //            frontCoverArtFileSize = file.Tag.Pictures[0].Data.Data.Length;
        //            image = Image.FromStream(ms);
        //        }
        //    }

        //    if(ms != null)
        //        ms.Close();

        //    return image;
        //}

        //private string FormatTrackNumbers(uint track, uint trackCount)
        //{
        //    if (track == 0 || (track == 0 && trackCount == 0))
        //        return string.Empty;

        //    if (track != 0 && trackCount == 0)
        //        return string.Format("{0:0#}", track);

        //    return string.Format("{0:0#}/{1:0#}", track, trackCount);
        //}

        //private string FormatTracks(string number)
        //{
        //    if (string.IsNullOrEmpty(number))
        //        return string.Empty;

        //    string[] trackNumber = number.Split('/');

        //    if (trackNumber.Length == 0)
        //        return string.Empty;

        //    string track = string.Empty;
        //    string ofTrack = string.Empty;
        //    int itrack;

        //    if (int.TryParse(trackNumber[0], out itrack))
        //    {
        //        track = string.Format("{0:0#}", itrack);
        //    }

        //    if (trackNumber.Length > 1)
        //    {
        //        int iofTrack;
        //        if (int.TryParse(trackNumber[1], out iofTrack))
        //        {
        //            ofTrack = string.Format("{0:0#}", iofTrack);
        //        }
        //    }

        //    if (string.IsNullOrEmpty(track) || (string.IsNullOrEmpty(track) && string.IsNullOrEmpty(ofTrack)))
        //    {
        //        return string.Empty;
        //    }

        //    if (!string.IsNullOrEmpty(track) && string.IsNullOrEmpty(ofTrack))
        //    {
        //        return track;
        //    }

        //    return string.Format("{0}/{1}", track, ofTrack);
        //}

        //private Image GetImageFromPictureFrame(ID3PictureFrame picture)
        //{
        //    Bitmap bitmap;

        //    BitmapFrame cover = picture.GetBitmapFrame();

        //    byte[] b = picture.PictureData;

        //    _artSize = b.Length;

        //    using (MemoryStream outStream = new MemoryStream())
        //    {
        //        BitmapEncoder enc = new JpegBitmapEncoder();
        //        enc.Frames.Add(BitmapFrame.Create(cover));
        //        enc.Save(outStream);
        //        bitmap = new Bitmap(outStream, true);

        //        outStream.Close();
        //    }

        //    return bitmap;
        //}

        //public void RemoveArt()
        //{
        //    for (int i = 0; i < _flacTagger.Arts.Count; i++)
        //    {
        //        if (_flacTagger.Arts[i].PictureType == ID3PictureType.FrontCover)
        //        {
        //            _flacTagger.RemoveArt(_flacTagger.Arts[i]);

        //            _flacTagger.SaveMetadata();
        //        }
        //    }
        //}

        //public void RemoveArt()
        //{
        //    for (int i = 0; i < _flacTagger.Arts.Count; i++)
        //    {
        //        if (_flacTagger.Arts[i].PictureType == ID3PictureType.FrontCover)
        //        {
        //            _flacTagger.RemoveArt(_flacTagger.Arts[i]);

        //            _flacTagger.SaveMetadata();
        //        }
        //    }
        //}

        //public void SaveArt(BitmapFrame bitmapFrame)
        //{
        //    //BitmapFrame bf = BitmapFrame.Create(bytes, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

        //    ID3PictureFrame pictureFrame = new ID3PictureFrame(bitmapFrame, ID3PictureType.FrontCover);

        //    _flacTagger.AddArt(pictureFrame);

        //    _flacTagger.SaveMetadata();
        //}

        //private ID3PictureFrame GetPictureFrameFromImage(Image image)
        //{
        //    var stream = new MemoryStream();
        //    image.Save(stream, ImageFormat.Jpeg);
        //    Byte[] bytes = stream.ToArray();
        //    ID3PictureFrame pictureFrame = new ID3PictureFrame(bytes, ID3PictureType.FrontCover);

        //    stream.Close();

        //    return pictureFrame;
        //}

        //public void SaveArt(byte[] bytes)
        //{

        //    _taglibfile.Tag.Pictures[0].Data.Add(bytes);
        //    _taglibfile.Tag.Pictures[0].Type = PictureType.FrontCover;

        //    BitmapFrame bf = BitmapFrame.Create(bytes, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

        //    ID3PictureFrame pictureFrame = new ID3PictureFrame(bytes, ID3PictureType.FrontCover);

        //    _flacTagger.AddArt(pictureFrame);

        //    _flacTagger.SaveMetadata();
        //}

        #endregion
    }
}
